package ldh.im.fxbase.util;

import javafx.concurrent.Task;

import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.logging.Logger;

public class ThreadPoolUtil {

    private static final ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
    private static final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);

    private static final Logger LOGGER = LoggerUtil.getFileLogger(ThreadPoolUtil.class);

    public static void close() {
        executorService.shutdownNow();
        scheduledExecutorService.shutdownNow();
    }

    public static <V> Future<V> submit(Callable<V> callable) {
        loggerThreadPool();
        return executorService.submit(()->{
            try {
               return (V)callable.call();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        });
    }

    public static <V> Future<V> submit(Runnable runnable) {
        loggerThreadPool();
        return (Future<V>) executorService.submit(()->{
            try {
                runnable.run();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    public static <V> Future<V> submit(Runnable runnable, Consumer<String> consumer) {
        loggerThreadPool();
        return (Future<V>) executorService.submit(()->{
            String errorMessage = null;
            try {
                runnable.run();
            } catch (Exception e) {
                errorMessage = e.getMessage();
            }
            if (errorMessage != null && consumer != null) {
                consumer.accept(errorMessage);
            }
        });
    }

    public static <V> ScheduledFuture<V> schedule(Runnable runnable, int milisecond) {
        Task<Void> task = new Task<Void>() {
                protected Void call() {
                    try {
                        runnable.run();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return null;
                }
        };

        return (ScheduledFuture<V>) scheduledExecutorService.schedule(task, milisecond, TimeUnit.MILLISECONDS);
    }

    public static <V> ScheduledFuture<V> schedule(Callable<V> callable) {
        return (ScheduledFuture<V>) scheduledExecutorService.schedule(()->{
            try {
                callable.call();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, 100, TimeUnit.MILLISECONDS);
    }

    private static void loggerThreadPool() {
        LOGGER.info("线程池中线程数目：" + executorService.getPoolSize()
                + "，队列中等待执行的任务数目：" + executorService.getQueue().size()
                + "，已执行完的任务数目：" + executorService.getCompletedTaskCount()
                + "，活动线程数目：" + executorService.getActiveCount()
        );
    }
}
